\documentclass[UTF8]{ctexart}
\usepackage{listings} 
\usepackage{xcolor}
\usepackage{fancyhdr}%设置页脚页眉需要的包
\pagestyle{fancy}
\usepackage{graphicx}
\usepackage{cite}
\usepackage{tikz}
\documentclass{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amsthm}
\usepackage{xeCJK}
\usepackage{graphicx}
\usepackage{fullpage}
\usepackage{float}
\usepackage{gnuplottex}
\usepackage{geometry}
\usepackage{enumitem}
\usepackage{verbatimbox}
\usepackage{amsfonts,amssymb} 
\usepackage[ruled,linesnumbered]{algorithm2e}
\usepackage[colorlinks,linkcolor=blue,citecolor=blue]{hyperref}
\usepackage{cite}
\CTEXsetup[format={\Large\bfseries}]{section}
\newtheorem{example}{例}             % 整体编号
\newtheorem{theorem}{定理}[section]  % 按 section 编号
\newtheorem{definition}{定义}
\newtheorem{axiom}{公理}
\newtheorem{property}{性质}
\newtheorem{proposition}{命题}
\newtheorem{lemma}{引理}
\newtheorem{corollary}{推论}
\newtheorem{remark}{注解}
\newtheorem{condition}{条件}
\newtheorem{conclusion}{结论}
\newtheorem{assumption}{假设}
\newcommand{\enabstractname}{Abstract}
\newenvironment{enabstract}{%
    \par\small
    \noindent\mbox{}\hfill{\bfseries \enabstractname}\hfill\mbox{}\par
    \vskip 2.5ex}{\par\vskip 2.5ex}
\usetikzlibrary{positioning, shapes.geometric}
\lstset{
  language=C++,
  frame=shadowbox,
  rulesepcolor=\color{red!20!green!20!blue!20},
  keywordstyle=\color{blue!90}\bfseries,
  commentstyle=\color{red!10!green!70}\textit,
  showstringspaces=false,
  numbers=left,
  numberstyle=\tiny,
  stringstyle=\ttfamily,
  breaklines=true,
  extendedchars=false,
  texcl=true}

\title{Project02}

\author{韩骐骏 \\ (数学科学学院)信息与计算科学3200103585}

\begin{document}

\maketitle

\section{设计思路}
\subsection{程序设计}
使用了自己设计的矩阵类Matrix.h，重载了加减乘运算符和调用运算符，并添加了矩阵求逆的函数；
使用了自己编写的设计函数的基类Function.h，其中提供了数值法求偏导函数值的功能。\\
在MultiGrid.h中，设计了MultiGrid<1>、MultiGrid<2>两个类，分别用于求解一维、二维微分方程。\\
在MULTIGRID<1>中，私有成员包含描述最粗网格的网格数n、描述最细网格数之于最粗网格数的倍数cycle\_depth、描述最细网格的网格间距h、存储最细网格的网格点(包含0和1两个点)的vector<double> x，另外还包括存储最细网格上的边界条件离散值f、存储求得的函数值的u,存储边界条件类型的type。另外私有成员还有所求函数u\_func，仅用于消除常数差以及测试时的误差分析，func存储条件函数。私有成员还包括限制算子函数(full-weighting和injection)、插入算子(linear)以及V\_\_cycle()、FMG()两个函数。公有成员包含基本构造函数（其中用户需要自己输入边界条件类型）、V\_cycle()函数（引用私有成员里的V\_\_cycle()函数）、FMG()函数（引用私有成员里的FMG()函数）、网格点函数值按矩阵形式的打印函数以及误差在不同范数下的值（需要用户输入范数）。其中V-cycle和FMG的设计模式即参考书上提供的理论。\\
MULTIGRID<2>即为MULTIGRID<1>的推广，设计方法基本相似，不再赘述。\\
在主程序main.cpp中，引入以上头文件并针对$9.5II$里的问题和自己设计的四个例子进行求解，绘制了图像，并求出不同范数下的误差并分析收敛速度。
\subsection{输入参数}
用户必须提供边界条件函数和所求实际函数（仅用于误差分析），还要提供最粗网格的网格点数和边界条件类型（string型，"D""N""M"分别代表Dirichlet条件、Nuemann条件和混合条件）以及网格重数（即cycle\_depth,描述最细网格数(横向)之于最粗网格数(横向)的倍数）。
\subsection{I(a)}
boundary conditions:仅设计了Dirichlet条件下的V\_cycle和FMG方法。
\subsection{I(b)}
restriction operators:实现了full weighting和injection两种限制算子（以函数形式，输入向量并返回向量）。
\subsection{I(c)}
interpolation operators:实现了linear插入算子（以函数形式，输入向量并返回向量）。
\subsection{I(d)}
cycles:在一维、二维上均实现了V\_cycle和FMG两种多重网格法。
\subsection{I(e)}
stopping criteria:用户可以修改最大迭代次数。
\subsection{I(f)}
the initial guess:为零向量。
\subsection{Extra credits(a)}
整个包中使用模版类进行编程，其中以$int dim$作为模版参数，MULTIGRID<1>为针对一维微分方程的求解，MULTIGRID<2>为针对二维微分方程的求解，在主程序中可以通过修改该模版参数来决定一维或二维求解。

\section{问题求解}
\subsection{9.5II}
题目要求在二维上对$u(x,y)=e^{y+sin(x)}$分别在$n=48$的网格上用V\_cycle和FMG两种多重网格法进行求解测试，经过主程序测试，V\_cycle方法的2-norm绝对误差和相对误差分别为$0.79885*10^{-6},9.07308*10^{-5}$，FMG方法的2-norm绝对误差和相对误差分别为$5.80232*10^{-6},0.000188095$，V\_cycle和FMG分别绘制实际函数、拟合函数、误差函数图像如图(其中误差函数z轴的单位为$10^{-5}$)：
\begin{figure}[H]
    \centering
    \includegraphics[width=10cm]{9.5.2_V-cycle.png}
    \caption{9.5.2\_V-cycle}
    \label{fig:galaxy}
\end{figure}
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{9.5.2_FMG.png}
    \caption{9.5.2\_FMG}
    \label{fig:galaxy}
\end{figure}
\subsection{四个测试函数}
另外自己编写了四个测试函数（两个一维，两个二维）：$$u_1(x)=16sin(\pi*x)+5*sin(16\pi x)$$ $$u_2(x)=e^xsin(\pi x)+cos(\pi x/2)+x-1$$ $$u_3(x,y)=256(x^2y^2-x^2y-xy^2+xy)$$ $$u_4(x,y)=16sin(\pi*x)+5*sin(16\pi x)$$ 并分别在$n=192$或$n=48$的网格上用V\_cycle和FMG方法测试，绘制原函数图像和拟合图像函数以及局部放大图或误差函数图如下（主程序运行时输出对应的2-norm下的绝对误差和相对误差）：
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{test1_V-cycle.png}
    \caption{u1\_V-cycle}
    \label{fig:galaxy}
\end{figure}
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{test3_FMG.png}
    \caption{u1\_FMG}
    \label{fig:galaxy}
\end{figure}
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{test2_V-cycle.png}
    \caption{u2\_V-cycle}
    \label{fig:galaxy}
\end{figure}
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{test4_FMG.png}
    \caption{u2\_FMG}
    \label{fig:galaxy}
\end{figure}
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{test5_V-cycle.png}
    \caption{u3\_V-cycle}
    \label{fig:galaxy}
\end{figure}
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{test7_FMG.png}
    \caption{u3\_FMG}
    \label{fig:galaxy}
\end{figure}
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{test6_V-cycle.png}
    \caption{u4\_V-cycle}
    \label{fig:galaxy}
\end{figure}
\begin{figure}[H]
    \centering
    \includegraphics[width=13cm]{test8_FMG.png}
    \caption{u4\_FMG}
    \label{fig:galaxy}
\end{figure}

\section{9.5III}
经过测试，我的程序V-cycle最精确能达到的精度为$\epsilon=10^{-6}$,FMG最精确能达到的精度为$\epsilon=10^{-7}$,若分别预定精度为$\epsilon=10^{-7}$、$\epsilon=10^{-8}$则无法达到。我认为这有多种可能：一是在每重网格上迭代的次数较少，无法产生质变，但多重网格法的初衷就是希望用较少的迭代次数产生较好的拟合效果；二是网格的重数较少，导致仍然有低频部分的误差难以消除，倘若增加重数（哪怕只增加一层）的话则程序结束的时间就会大大增加，在本程序中题目提供的函数和自己编写的测试函数的网格重数分别为4和6，都可以一秒内跑出来，但倘若分别加到5和7，则程序一分钟内也结束不了。

\end{document}
